/**************************************************************************
 * @name: POSIX.c
 * @brief: 匿名信号量代码练习一
 * @date: 2025/02/14
 * @author: boluzs@163.com
 * @note:
 * 练习:
 *      要求在进程中存在两条线程，主线程获取键盘的字符串并输入到数组中，
 *      子线程等待主线程输入完成后，在把数组中的字符串输出到终端。
 *      要求使用 POSIX 信号量实现线程的同步。
 * @version: 1.0.0
 * @Copyright (c) 2025 by boluzs@163.com, All Rights Reserved.
 **************************************************************************/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <stdlib.h>

#include <time.h>
#include <pthread.h>    
#include <unistd.h>
#include <semaphore.h>
#define FILE_PATH "./log.txt"

char data[128] = {0};

// 定义POSIX匿名信号量，只能在进程中的线程间使用，一般是用于多线程的同步
sem_t sem1;
sem_t sem2;

// 构造线程的回调函数 格式是固定的
void *threadA_handler(void *arg)
{
    for (;;)
    {
        // P操作
        sem_wait(&sem2);

        printf("输入的值: %s\n", data);

        // V操作
        sem_post(&sem1);
    }
}

// 构造线程的回调函数 格式是固定的
void *threadB_handler(void *arg)
{
    for (;;)
    {
        // P操作
        sem_wait(&sem1);

        int n = 0;
        while (n != 1)
        {
            printf("请输入字符串\n");
            n = scanf("%s", data);
            if (n != 1)
                printf("格式不正确!\n");
            while (getchar() != '\n')
                ;
        }

        // V操作
        sem_post(&sem2);
    }
}

int main()
{

    pthread_t newthreadA_id = 0; // 用于记录创建的新线程的ID，可以理解为是线程的句柄
    pthread_t newthreadB_id = 0; // 用于记录创建的新线程的ID，可以理解为是线程的句柄

    // 0.初始化POSIX匿名信号量,并且设置信号量初值为0
    sem_init(&sem1, 0, 1);
    sem_init(&sem2, 0, 0);

    // 1.创建新线程
    pthread_create(&newthreadA_id, NULL, threadA_handler, NULL);
    pthread_create(&newthreadB_id, NULL, threadB_handler, NULL);

    // 2.
    pthread_join(newthreadA_id, NULL);
    pthread_join(newthreadB_id, NULL);

    // 主线程的任务
    for (;;)
    {
    }
    return 0;
}
